package cc.magicjson.example.demo.chatgpt;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Predicate;

enum Door1 {
    FIRST, SECOND, THIRD
}

public class MontyHallSimulation1 {
    private static final Random random = new Random();

    public static void main(String[] args) {
        int totalSimulations = 1000;
        long winCount = simulateMontyHall(totalSimulations);
        double winPercentage = (double) winCount / totalSimulations * 100;

        System.out.println("Simulation Results:");
        System.out.println("Total Simulations: " + totalSimulations);
        System.out.println("Wins: " + winCount);
        System.out.println("Win Percentage: " + winPercentage + "%");
    }

    private static long simulateMontyHall(int totalSimulations) {
        return java.util.stream.IntStream.range(0, totalSimulations)
                .filter(i -> simulateSingleMontyHallGame())
                .count();
    }

    private static boolean simulateSingleMontyHallGame() {
        List<Door1> doors = new ArrayList<>();
        doors.add(Door1.FIRST);
        doors.add(Door1.SECOND);
        doors.add(Door1.THIRD);

        Door1 carDoor1 = chooseRandomDoor1();
        Door1 selectedDoor1 = chooseRandomDoor1();

        Predicate<Door1> isNotSelectedOrCar = door -> door != selectedDoor1 && door != carDoor1;

        List<Door1> doorsToReveal = doors.stream()
                .filter(isNotSelectedOrCar)
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        Door1 revealedDoor1 = doorsToReveal.get(random.nextInt(doorsToReveal.size()));

        List<Door1> availableDoor1sAfterReveal = doors.stream()
                .filter(isNotSelectedOrCar.and(door -> door != revealedDoor1))
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        if (availableDoor1sAfterReveal.isEmpty()) {
            // 如果没有可用的门，重新选择一扇门
            availableDoor1sAfterReveal.add(doors.stream()
                    .filter(isNotSelectedOrCar)
                    .findFirst()
                    .orElseThrow(IllegalStateException::new));
        }

        Door1 finalChoice = availableDoor1sAfterReveal.get(0);

        return finalChoice == carDoor1;
    }

    private static Door1 chooseRandomDoor1() {
        Door1[] doors = Door1.values();
        return doors[random.nextInt(doors.length)];
    }
}
